package com.qike.duola.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.common.collect.ImmutableMap;
import com.qike.duola.dto.UserAddDto;
import com.qike.duola.dto.UserDelDto;
import com.qike.duola.dto.UserEditDto;
import com.qike.duola.dto.UserListDto;
import com.qike.duola.response.BaseResult;
import com.qike.duola.response.RetResponse;
import com.qike.duola.service.IsysResourceService;
import com.qike.duola.service.IsysUserService;
import com.qike.duola.shiro.LoginUser;
import com.qike.duola.utils.TokenUtil;
import com.qike.duola.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mobile.device.Device;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController( )
@Api(description = "登录用户控制器")
@CrossOrigin
public class LoginController {


    private static Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private DefaultKaptcha captchaProducer;
    @Autowired
    private IsysUserService userService;
    @Autowired
    private IsysResourceService isysResourceService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @GetMapping(value = "/captcha")
    public Map<String, String> captcha() {
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            String capText = captchaProducer.createText();
            String uuid = UUID.randomUUID().toString();
            redisTemplate.boundValueOps(uuid).set(capText, 60, TimeUnit.SECONDS);
            BufferedImage bi = captchaProducer.createImage(capText);
            ImageIO.write(bi, "png", baos);
            String imgBase64 = Base64.encodeBase64String(baos.toByteArray());
            return ImmutableMap.of(uuid, "data:image/jpeg;base64," + imgBase64);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    @PostMapping(value = "/login")
    @ApiOperation("登录")
    @ResponseBody
    public BaseResult login(@RequestBody LoginUser loginUser, HttpServletRequest request, HttpServletResponse response, Device device) throws IOException {
        try {
            LoginVo login = userService.login(loginUser.getUsername(), loginUser.getPassword(), device, request, response);
            return RetResponse.makeOKRsp(login);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }

    @GetMapping(value = "/getUserInfo")
    @ApiOperation("获取用户信息")
    @ResponseBody
    @ApiResponses({
            @ApiResponse(code = 200, message = "ok", response = GetUserInfoVo.class)
    })
    public BaseResult getUserInfo() throws IOException {
        try {
            GetUserInfoVo userInfoVo = userService.getUserInfo();
            return RetResponse.makeOKRsp(userInfoVo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }


    /**
     * 检查是否登录
     *
     * @param token
     * @return
     */
    @GetMapping(value = "/checkLogin")
    @ApiOperation("检查是否登录")
    public Object checkLogin(@CookieValue("token") String token) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);
        if (StringUtils.isEmpty(token)) {
            jsonObject.put("msg", "令牌为空");
        }

        // 根据token获取用户信息

        // 检查token合法性及用户身份

        return jsonObject;
    }


    /**
     * 登出
     *
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @GetMapping(value = "/logout")
    @ApiOperation("登出")
    public Object logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
//        Optional<Cookie> cookie = Arrays.stream(request.getCookies())
//                .filter(ck -> "token".equals(ck.getName()))
//                .limit(1)
//                .map(ck -> {
//                    ck.setMaxAge(0);
//                    ck.setHttpOnly(true);
//                    ck.setPath("/");
//                    return ck;
//                })
//                .findFirst();
        String cookie = request.getHeader("token");
//        response.addCookie(cookie.get());
        response.flushBuffer();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 200);
        jsonObject.put("msg", "success");
        return jsonObject;
    }


    /**
     * 更新token
     *
     * @param token
     * @return
     */
    @PostMapping("/token/refresh")
    @ApiOperation("更新token")
    public Object refreshToken(@CookieValue(value = "token") String token) {
        JSONObject jsonObject = new JSONObject();
        String newToken = tokenUtil.refreshToken(token);
        jsonObject.put("code", 200);
        jsonObject.put("msg", "success");
        jsonObject.put("token", newToken);
        jsonObject.put("timestamp", Calendar.getInstance().getTimeInMillis());
        return jsonObject;
    }

    /**
     * 更新token
     *
     * @param token
     * @return
     */
    @GetMapping("/message/list")
    @RequiresPermissions("ccc:ddd:bbba")
    public Object messageList(@CookieValue(value = "token") String token) {
        System.out.println("messageList");
        return "messageList";
    }

    /**
     * 获取用户所有菜单
     *
     * @return
     */
    @GetMapping("/menuList")
    @ApiOperation("获取用户所有菜单")
    @ResponseBody
    public BaseResult menuList() {
        try {
            Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
            ResourceListVo menuList = isysResourceService.getMenuList(userId);
            return RetResponse.makeOKRsp(menuList);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }

    /**
     * 添加用户
     *
     * @return
     */
    @PostMapping("/userAdd")
    @ApiOperation("添加用户")
    @ResponseBody
    public BaseResult userAdd(@RequestBody UserAddDto userAddDto) {
        try {
            userService.userAdd(userAddDto);
            return RetResponse.makeOKRsp();
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }

    /**
     * 编辑用户
     *
     * @return
     */
    @PostMapping("/userEdit")
    @ApiOperation("编辑用户")
    @ResponseBody
    public BaseResult userEdit(@RequestBody UserEditDto userEditDto) {
        try {
            userService.userEdit(userEditDto);
            return RetResponse.makeOKRsp();
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }

    /**
     * 删除用户
     *
     * @return
     */
    @PostMapping("/userDel")
    @ApiOperation("删除用户")
    @ResponseBody
    public BaseResult userDel(@RequestBody UserDelDto userDelDto) {
        try {
            userService.userDel(userDelDto);
            return RetResponse.makeOKRsp();
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }


    /**
     * 用户列表
     *
     * @return
     */
    @GetMapping("/userList")
    @ApiOperation("用户列表")
    @ResponseBody
    public BaseResult userList(UserListDto userListDto) {
        try {
            UserListVo vo = userService.userList(userListDto);
            return RetResponse.makeOKRsp(vo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }

    /**
     * 用户详情
     *
     * @return
     */
    @GetMapping("/userInfo")
    @ApiOperation("用户详情")
    @ResponseBody
    @ApiResponses({
            @ApiResponse(code = 200, message = "ok", response = UserInfoVo.class)
    })
    public BaseResult userInfo(Long id) {
        try {
            UserInfoVo vo = userService.userInfo(id);
            return RetResponse.makeOKRsp(vo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }

    /**
     * 人员下拉列表
     *
     * @return
     */
    @GetMapping("/userPullList")
    @ApiOperation("人员下拉列表")
    @ResponseBody
    @ApiResponses({
            @ApiResponse(code = 200, message = "ok", response = UserPullListVo.class)
    })
    public BaseResult userPullList(String name) {
        try {
            List<UserPullListVo> vo = userService.userPullList(name);
            return RetResponse.makeOKRsp(vo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }


    /**
     * 根据部门,姓名查询人员下拉列表
     *
     * @return
     */
    @GetMapping("/userPullListByDeptId")
    @ApiOperation("根据部门,姓名查询人员下拉列表")
    @ResponseBody
    @ApiResponses({
            @ApiResponse(code = 200, message = "ok", response = UserPullListVo.class)
    })
    public BaseResult userPullListByDeptId(Integer deptId,String name ) {
        try {
            List<UserPullListVo> vo = userService.userPullListByDeptId(deptId,name);
            return RetResponse.makeOKRsp(vo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return RetResponse.makeErrRsp(e.getMessage());
        }
    }
}
